package service

import (
	"context"
	"fmt"
	"log"

	"github.com/shopspring/decimal"
	"gorm.io/gorm"

	"gitee.com/wangshh_123/cross-pay-go/src/models"
)

// BalanceSyncService 余额同步服务
type BalanceSyncService struct {
	db *gorm.DB
}

// NewBalanceSyncService 创建余额同步服务
func NewBalanceSyncService(db *gorm.DB) *BalanceSyncService {
	return &BalanceSyncService{
		db: db,
	}
}

// SyncCardBalance 同步卡片余额（手动设置）
func (s *BalanceSyncService) SyncCardBalance(ctx context.Context, cardID string, newBalance decimal.Decimal) error {
	// 查询卡片信息
	var userCard models.UserCard
	if err := s.db.Where("card_id = ?", cardID).First(&userCard).Error; err != nil {
		return fmt.Errorf("card not found: %v", err)
	}

	log.Printf("[BalanceSync] 开始同步卡片余额: CardID=%s, Platform=%s, 新余额=%s",
		cardID, userCard.Platform, newBalance.String())

	// 更新本地数据库中的余额
	if err := s.db.Model(&userCard).Update("TotalTransferAmount", newBalance).Error; err != nil {
		return fmt.Errorf("failed to update local balance: %v", err)
	}

	log.Printf("[BalanceSync] 卡片余额同步成功: CardID=%s, Balance=%s", cardID, newBalance.String())
	return nil
}

// GetCardBalance 获取卡片当前余额
func (s *BalanceSyncService) GetCardBalance(ctx context.Context, cardID string) (decimal.Decimal, error) {
	var userCard models.UserCard
	if err := s.db.Where("card_id = ?", cardID).First(&userCard).Error; err != nil {
		return decimal.Zero, fmt.Errorf("card not found: %v", err)
	}

	return userCard.TotalTransferAmount, nil
}

// ListCardsWithZeroBalance 列出余额为0的卡片
func (s *BalanceSyncService) ListCardsWithZeroBalance(ctx context.Context) ([]models.UserCard, error) {
	var userCards []models.UserCard
	if err := s.db.Where("TotalTransferAmount = ?", decimal.Zero).Find(&userCards).Error; err != nil {
		return nil, fmt.Errorf("failed to get cards with zero balance: %v", err)
	}

	return userCards, nil
}

// ListCardsByPlatform 按平台列出卡片
func (s *BalanceSyncService) ListCardsByPlatform(ctx context.Context, platform string) ([]models.UserCard, error) {
	var userCards []models.UserCard
	if err := s.db.Where("platform = ?", platform).Find(&userCards).Error; err != nil {
		return nil, fmt.Errorf("failed to get cards by platform: %v", err)
	}

	return userCards, nil
}

// UpdateCardBalanceByUser 根据用户ID更新卡片余额
func (s *BalanceSyncService) UpdateCardBalanceByUser(ctx context.Context, userID int64, cardID string, newBalance decimal.Decimal) error {
	var userCard models.UserCard
	if err := s.db.Where("card_id = ? AND user_id = ?", cardID, userID).First(&userCard).Error; err != nil {
		return fmt.Errorf("card not found or not owned by user: %v", err)
	}

	if err := s.db.Model(&userCard).Update("TotalTransferAmount", newBalance).Error; err != nil {
		return fmt.Errorf("failed to update card balance: %v", err)
	}

	log.Printf("[BalanceSync] 用户卡片余额更新成功: UserID=%d, CardID=%s, Balance=%s",
		userID, cardID, newBalance.String())
	return nil
}

// GetBalanceSummary 获取余额统计信息
func (s *BalanceSyncService) GetBalanceSummary(ctx context.Context) (map[string]interface{}, error) {
	var totalCards int64
	var zeroBalanceCards int64
	var totalBalance decimal.Decimal

	// 统计总卡片数
	if err := s.db.Model(&models.UserCard{}).Count(&totalCards).Error; err != nil {
		return nil, fmt.Errorf("failed to count total cards: %v", err)
	}

	// 统计余额为0的卡片数
	if err := s.db.Model(&models.UserCard{}).Where("TotalTransferAmount = ?", decimal.Zero).Count(&zeroBalanceCards).Error; err != nil {
		return nil, fmt.Errorf("failed to count zero balance cards: %v", err)
	}

	// 计算总余额
	if err := s.db.Model(&models.UserCard{}).Select("COALESCE(SUM(TotalTransferAmount), 0) as total").Scan(&totalBalance).Error; err != nil {
		return nil, fmt.Errorf("failed to calculate total balance: %v", err)
	}

	// 按平台统计
	var platformStats []struct {
		Platform string          `json:"platform"`
		Count    int64           `json:"count"`
		Balance  decimal.Decimal `json:"balance"`
	}

	if err := s.db.Model(&models.UserCard{}).
		Select("platform, COUNT(*) as count, COALESCE(SUM(TotalTransferAmount), 0) as balance").
		Group("platform").
		Scan(&platformStats).Error; err != nil {
		return nil, fmt.Errorf("failed to get platform stats: %v", err)
	}

	return map[string]interface{}{
		"totalCards":       totalCards,
		"zeroBalanceCards": zeroBalanceCards,
		"totalBalance":     totalBalance.String(),
		"platformStats":    platformStats,
	}, nil
}
